package com.weigecoder.warehouse.service.impl;

import com.alibaba.fastjson.JSON;
import com.weigecoder.warehouse.constant.WarehouseConstants;
import com.weigecoder.warehouse.dto.AssignRoleDto;
import com.weigecoder.warehouse.entity.Result;
import com.weigecoder.warehouse.entity.Role;
import com.weigecoder.warehouse.exception.BusinessException;
import com.weigecoder.warehouse.mapper.AuthMapper;
import com.weigecoder.warehouse.mapper.RoleMapper;
import com.weigecoder.warehouse.page.Page;
import com.weigecoder.warehouse.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* 针对表【role(角色表)】的数据库操作Service实现
*/

//指定缓存的名称
// @CacheConfig(cacheNames = "com.weigecoder.warehouse.service.impl.RoleServiceImpl")
@Service
public class RoleServiceImpl implements RoleService{
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private AuthMapper authMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 查询所有角色
     */
    //查询方法上标注Cacheable指定缓存的键
    // @Cacheable(key = "'all:role'")
    @Override
    public List<Role> queryAllRole() {

        String cache = stringRedisTemplate.opsForValue().get(WarehouseConstants.ALL_ROLE);
        if (StringUtils.hasText(cache)){
            List<Role> roleList = JSON.parseArray(cache, Role.class);
            return roleList;
        }
        //缓存不存在，从数据库中查询
        List<Role> roles = roleMapper.selectAllRole();
        //存入缓存
        stringRedisTemplate.opsForValue().set(WarehouseConstants.ALL_ROLE,JSON.toJSONString(roles),3, TimeUnit.DAYS);
        return roles;
    }

    /**
     * //根据用户ID查询用户角色
     * @param userId
     * @return
     */
    @Override
    public List<Role> queryRolesByUserId(int userId) {
        return roleMapper.selectRolesByUserId(userId);
    }

    /**
     * 给用户分配角色
     * @param assignRoleDto
     */
    @Transactional
    @Override
    public void assignRole(AssignRoleDto assignRoleDto) {
        //拿到用户ID和前端分配给用户的roleCheckList
        Integer userId = assignRoleDto.getUserId();
        List<String> roleNameList = assignRoleDto.getRoleCheckList();

        //清除权限树缓存
        stringRedisTemplate.delete(WarehouseConstants.AUTH_TREE_PREFIX+userId);
        //根据用户id删除给用户已分配的所有角色
        roleMapper.delRoleByUserId(userId);

        //循环添加用户角色关系
        for (String roleName : roleNameList) {
            //根据当前角色名查询当前角色的id
            Integer roleId = roleMapper.queryRoleIdByRoleName(roleName);
            //操作用户角色中间表，添加用户角色关系，给用户分配角色
            roleMapper.insertUserRole(userId,roleId);
        }
    }

    /**
     * 分页查询角色的业务方法
     * @param page
     * @param role
     * @return
     */
    @Override
    public Page queryRolePage(Page page, Role role) {
        //查询角色总行数
        int roleCount = roleMapper.selectRoleCount(role);
        //分页查询角色
        List<Role> roleList = roleMapper.selectRolePage(page, role);
        //将查询到的总行数和当前页数据组装到Page对象
        page.setTotalNum(roleCount);
        page.setResultList(roleList);
        return page;
    }

    /**
     * 修改角色状态的业务方法  启用和禁用角色
     * @param role
     * @return
     */
    @Override
    public Result updateRoleState(Role role) {
        //删除缓存
        stringRedisTemplate.delete(WarehouseConstants.ALL_ROLE);
        //根据角色id修改角色状态,启用和禁用角色
        int i = roleMapper.updateRoleState(role);
        if(i>0){
            return Result.ok("启用或禁用角色成功！");
        }
        return Result.err(Result.CODE_ERR_BUSINESS, "启用或禁用角色失败！");
    }

    /**
     * 添加角色
     * @param role
     * @return
     */
    /**
     * // 清理redis缓存
     * @param role
     * @return
     */
    @CacheEvict(key = "'all:role'")
    @Override
    public Result saveRole(Role role) {
        //根据角色名或角色代码查询角色
        Role oldRole = roleMapper.findRoleByNameOrCode(role.getRoleName(), role.getRoleCode());
        if(oldRole!=null){
            return Result.err(Result.CODE_ERR_BUSINESS, "该角色已存在！");
        }
        //删除缓存
        stringRedisTemplate.delete(WarehouseConstants.ALL_ROLE);
        //角色不存在,添加角色
        int i = roleMapper.insertRole(role);
        if (i>0){
            return Result.ok("添加角色成功！");
        }
        return Result.err(Result.CODE_ERR_BUSINESS,"添加角色失败！");

    }

    /**
     * 删除角色的业务方法
     * @param roleId
     */
    @Transactional
    @Override
    public void deleteRole(Integer roleId) {
        //删除缓存
        stringRedisTemplate.delete(WarehouseConstants.ALL_ROLE);
        //根据角色id删除角色
        int i = roleMapper.deleteRoleById(roleId);
        if(i>0){
            //删除用户分配好的角色  中间表
            roleMapper.deleteUserAndRoleByRoleId(roleId);
            //根据角色id删除给角色已分配的所有权限(菜单)
            authMapper.delAuthByRoleId(roleId);
        }else {
            throw new BusinessException("删除失败！");
        }
    }


    //修改角色描述的业务方法
    @Override
    public Result updateRoleDesc(Role role) {
        //删除缓存
        stringRedisTemplate.delete(WarehouseConstants.ALL_ROLE);
        //根据角色id修改角色描述
        int i = roleMapper.updateDescById(role);
        if(i>0){
            return Result.ok("角色修改成功！");
        }
        return Result.err(Result.CODE_ERR_BUSINESS, "角色修改失败！");
    }

    /**
     * 根据角色ID查询角色已分配的权限(菜单)的业务方法
     * @param roleId
     * @return
     */
    @Override
    public List<Integer> queryAuthByRoleId(Integer roleId) {
        //根据角色id查询角色已分配的所有权限(菜单)的id
        return roleMapper.findAuthByRoleId(roleId);
    }

    @Override
    public List<Integer> queryAuthByUserId(Integer userId) {
        return roleMapper.findAuthByUserId(userId);
    }
}




